<template>
	<view class="online-custom-widget">
		<online-custom-group v-if="widget.widgetType === SysCustomWidgetType.CellGroup" :widget="widget" />
		<online-custom-tabs v-if="widget.widgetType === SysCustomWidgetType.Tabs" :widget="widget" />
		<select-filter
			v-if="widget.widgetType === SysCustomWidgetType.MobileRadioFilter || widget.widgetType === SysCustomWidgetType.MobileCheckBoxFilter"
			:widget="widget"
			:dataList="getWidgetProps.dataList"
			:label="widget.showName"
			:multiple="multiSelect"
			:value="bindValue"
			@input="onValueInput"
			@change="onValueChange"
		/>
		<search-filter
			v-if="widget.widgetType === SysCustomWidgetType.MobileInputFilter"
			:label="widget.showName"
			:value="bindValue"
			@input="onValueInput"
			@change="onValueChange"
		/>
		<switch-filter
			v-if="widget.widgetType === SysCustomWidgetType.MobileSwitchFilter"
			:label="widget.showName"
			:value="bindValue"
			@input="onValueInput"
			@change="onValueChange"
		/>
		<number-range-filter
			v-if="widget.widgetType === SysCustomWidgetType.MobileNumberRangeFilter"
			:label="widget.showName"
			:value="bindValue"
			@input="onValueInput"
			@change="onValueChange"
		/>
		<date-range-filter
			v-if="widget.widgetType === SysCustomWidgetType.MobileDateRangeFilter"
			:widget="widget"
			:label="widget.showName"
			:value="bindValue"
			@input="onValueInput"
			@change="onValueChange"
		/>
		<online-field-label v-if="isLabelWidget" :value="bindValue" :widget="widget" />
		<field-radio
			ref="widgetImpl"
			v-if="widget.widgetType === SysCustomWidgetType.Radio && !form().readOnly"
			:widget="widget"
			:label="widget.showName"
			:value="bindValue"
			:dataList="dictDataList"
			:direction="getWidgetProps.direction"
			:iconSize="getWidgetProps['icon-size']"
			:required="widget.props.required"
			:disabled="getWidgetProps.disabled"
			:rules="form().rules[widget.propString]"
			:prop="widget.propString"
			@input="onValueInput"
			@change="onValueChange"
		/>
		<field-cascader
			ref="widgetImpl"
			v-if="widget.widgetType === SysCustomWidgetType.Cascader && !form().readOnly"
			:label="widget.showName"
			:dataList="getWidgetProps.dataList"
			:multiple="multiSelect"
			:value="bindValue"
			:required="widget.props.required"
			:disabled="getWidgetProps.disabled"
			:rules="form().rules[widget.propString]"
			:prop="widget.propString"
			@input="onValueInput"
			@change="onValueChange"
		/>
		<online-custom-image
			v-if="widget.widgetType === SysCustomWidgetType.Image && !form().readOnly"
			:value="bindValue"
			:widget="widget"
			:widgetProps="getWidgetProps"
			:src="getWidgetProps.src"
			:fit="getWidgetProps.fit"
			:round="getWidgetProps.round"
			:width="getWidgetProps.width"
			:height="getWidgetProps.height"
			:radius="getWidgetProps.radius"
		/>
		<online-relation-select
			ref="widgetImpl"
			v-if="widget.widgetType === SysCustomWidgetType.DataSelect && !form().readOnly"
			:widget="widget"
			:label="widget.showName"
			:required="widget.props.required"
			:props="getWidgetProps.props"
			:value="bindValue"
			:disabled="getWidgetProps.disabled"
			:rules="form().rules[widget.propString]"
			:prop="widget.propString"
			@input="onValueInput"
			@change="onValueChange"
		/>
		<user-select
			ref="widgetImpl"
			v-if="widget.widgetType === SysCustomWidgetType.UserSelect && !form().readOnly"
			:widget="widget"
			:label="widget.showName"
			:required="widget.props.required"
			:value="bindValue"
			:disabled="getWidgetProps.disabled"
			:rules="form().rules[widget.propString]"
			:prop="widget.propString"
			@input="onValueInput"
			@change="onValueChange"
		/>
		<dept-select
			ref="widgetImpl"
			v-if="widget.widgetType === SysCustomWidgetType.DeptSelect && !form().readOnly"
			:widget="widget"
			:label="widget.showName"
			:required="widget.props.required"
			:value="bindValue"
			:disabled="getWidgetProps.disabled"
			:rules="form().rules[widget.propString]"
			:prop="widget.propString"
			@input="onValueInput"
			@change="onValueChange"
		/>
		<field-calendar
			ref="widgetImpl"
			v-if="widget.widgetType === SysCustomWidgetType.Calendar && !form().readOnly" :widget="widget"
			:label="widget.showName"
			:required="widget.props.required"
			:color="getWidgetProps.color === '' ? undefined : getWidgetProps.color"
			:value="bindValue"
			:disabled="getWidgetProps.disabled"
			:rules="form().rules[widget.propString]"
			:prop="widget.propString"
			@input="onValueInput" @change="onValueChange"
		/>
		<field-stepper
			ref="widgetImpl"
			v-if="widget.widgetType === SysCustomWidgetType.Stepper && !form().readOnly"
			:widget="widget"
			:label="widget.showName" :required="widget.props.required"
			:step="getWidgetProps.step || 1"
			:min="getWidgetProps.min || 0"
			:max="getWidgetProps.max || 9999"
			:inputWidth="getWidgetProps.inputWidth"
			:inputHeight="getWidgetProps.buttonSize"
			:value="bindValue"
			:disabled="getWidgetProps.disabled"
			:rules="form().rules[widget.propString]"
			:prop="widget.propString"
			@input="onValueInput"
			@change="onValueChange"
		/>
		<field-select
			v-if="widget.widgetType === SysCustomWidgetType.Select && !form().readOnly"
			ref="widgetImpl"
			:label="widget.showName"
			:disabled="getWidgetProps.disabled"
			:required="widget.props.required"
			:dataList="getWidgetProps.dataList"
			:multiple="multiSelect"
			:value="bindValue"
			:rules="form().rules[widget.propString]"
			:prop="widget.propString"
			@input="onValueInput" @change="onValueChange"
		/>
		<field-input
			ref="widgetImpl"
			v-if="widget.widgetType === SysCustomWidgetType.Input && !form().readOnly"
			:rules="form().rules[widget.propString]"
			:prop="widget.propString"
			:label="widget.showName"
			:required="widget.props.required"
			:type="widget.props.type === 'textarea' ? 'textarea' : 'text'"
			:maxlength="(getWidgetProps.maxlength != null && getWidgetProps.maxlength > 0) ? getWidgetProps.maxlength : -1"
			:password="getWidgetProps['show-password']"
			:clearable="true"
			:placeholder="getWidgetProps.placeholder"
			:value="bindValue"
			:disabled="getWidgetProps.disabled"
			:readonly="getWidgetProps.readonly"
			@input="onValueInput"
			@change="onValueChange"
		/>
		<field-switch
			ref="widgetImpl"
			v-if="widget.widgetType === SysCustomWidgetType.Switch"
			:label="widget.showName"
			:required="widget.props.required"
			:value="bindValue"
			:disabled="getWidgetProps.disabled"
			:rules="form().rules[widget.propString]"
			:prop="widget.propString"
			@input="onValueInput"
			@change="onValueChange"
		/>
		<field-checkbox
			ref="widgetImpl"
			v-if="widget.widgetType === SysCustomWidgetType.CheckBox"
			:label="widget.showName"
			:dataList="dictDataList"
			:direction="getWidgetProps.direction"
			:value="bindValue"
			:disabled="getWidgetProps.disabled"
			:rules="form().rules[widget.propString]"
			:prop="widget.propString"
			@input="onValueInput"
			@change="onValueChange"
		/>
		<field-rate
			ref="widgetImpl"
			v-if="widget.widgetType === SysCustomWidgetType.Rate"
			:label="widget.showName"
			:count="getWidgetProps.count"
			:color="getWidgetProps.color === '' ? undefined : getWidgetProps.color"
			:voidColor="getWidgetProps['void-color']"
			:required="widget.props.required"
			:value="bindValue"
			:disabled="getWidgetProps.disabled"
			:rules="form().rules[widget.propString]"
			:prop="widget.propString"
			@input="onValueInput"
			@change="onValueChange"
		/>
		<online-custom-upload
			ref="widgetImpl"
			v-if="widget.widgetType === SysCustomWidgetType.Upload"
			:widget="widget"
			:label="widget.showName"
			:required="widget.props.required"
			:value="bindValue"
			:disabled="getWidgetProps.disabled"
			:readOnly="getWidgetProps.readonly"
			:rules="form().rules[widget.propString]"
			:prop="widget.propString"
			@input="onValueInput"
			@change="onValueChange"
		/>
		<online-custom-list
			v-if="widget.widgetType === SysCustomWidgetType.List"
			:widget="widget"
			:value="bindValue"
			:supportPullRefresh="false"
			@input="onValueInput"
			@change="onValueChange"
		/>
		<custom-text
			v-if="widget.widgetType === SysCustomWidgetType.Text"
			:value="bindValue"
			:align="getWidgetProps.align"
			:valign="getWidgetProps.valign"
			:fontSize="getWidgetProps.fontSize"
			:height="getWidgetProps.height"
			:padding="getWidgetProps.padding"
			:fontColor="getWidgetProps.fontColor"
			:fontBold="getWidgetProps.fontBold"
			:fontItalic="getWidgetProps.fontItalic"
			:isHtml="widget.column && widget.column.isRichText"
			@input="onValueInput"
			@change="onValueChange"
		/>
		<online-custom-chart v-if="isChart(widget.widgetType)" :widget="widget" :value="bindValue" />
		<field-signature
			v-if="widget.widgetType === SysCustomWidgetType.Signature"
			:label="widget.showName"
			:value="bindValue"
			:required="widget.props.required"
			:rules="form().rules[widget.propString]"
			:disabled="getWidgetProps.disabled"
			:height="widget.props.height"
			:backgroundColor="widget.props.backgroundColor"
			:penColor="widget.props.penColor"
			@input="onValueInput"
			@change="onValueChange"
		/>
		<!-- <field-cascader v-if="widget.widgetType === SysCustomWidgetType.Cascader" :widget="widget" :label="widget.showName" :value="bindValue" @input="onValueInput" @change="onValueChange" :required="widget.props.required" /> -->
		<!-- <online-custom-image v-if="widget.widgetType === SysCustomWidgetType.Image" :widget="widget" :src="widget.props.src" :align="widget.props.align" :fit="widget.props.fit" :width="widget.props.width" :height="widget.props.height" :round="widget.props.round" :radius="widget.props.radius" :label="widget.showName" :value="bindValue" @input="onValueInput" @change="onValueChange" :required="widget.props.required" /> -->
	</view>
</template>

<script>
	import {
		findItemFromList,
		treeDataTranslate
	} from '@/utils';
	import OnlineCustomGroup from './OnlineCustomGroup.vue'
	import OnlineCustomChart from './OnlineCustomChart.vue'
	import OnlineFieldLabel from './OnlineFieldLabel.vue'
	import OnlineCustomList from './OnlineCustomList.vue'
	import SelectFilter from '../SelectFilter.vue'
	import DateRangeFilter from '../DateRangeFilter.vue'
	import {
		isChart
	} from '@/views/online/utils.js';
	export default {
		name: 'onlineCustomWidget',
		options: {
			styleIsolation: 'shared', // 解除样式隔离
		},
		props: {
			value: {
				type: [String, Number, Boolean, Date, Object, Array]
			},
			widget: {
				type: Object,
				required: true
			}
		},
		components: {
			OnlineCustomGroup,
			OnlineCustomChart,
			OnlineFieldLabel,
			OnlineCustomList,
			SelectFilter,
			DateRangeFilter
		},
		inject: {
			form: {
				default: ''
			},
			parentWidget: {
				default: null
			}
		},
		data() {
			return {
				dictDataList: []
			}
		},
		methods: {
			isChart,
			parseValue(val) {
				let bindColumnType = this.getColumnDataType;
				if (this.widget.widgetType === this.SysCustomWidgetType.Switch) {
					// 根据绑定字段的类型，转换数据格式
					if (bindColumnType === 'Number') {
						return val ? 1 : 0;
					} else if (bindColumnType === 'String') {
						return val ? 'true' : 'false';
					} else if (bindColumnType !== 'Boolean') {
						return false;
					} else {
						return val;
					}
				}
				if (this.widget.widgetType === this.SysCustomWidgetType.Cascader) {
					if (this.multiSelect) {
						return val;
					} else {
						return Array.isArray(val) ? val[val.length - 1] : val;
					}
				} else {
					return val;
				}
			},
			onValueInput(val) {
				console.log(val);
				let tempValue = this.parseValue(val);
				if (this.multiSelect) {
					tempValue = (Array.isArray(tempValue) && tempValue.length > 0) ? tempValue.join(',') : undefined;
				}
				this.$emit('input', tempValue);
			},
			onValueChange(val, selectRow) {
				let tempVal = this.parseValue(val);
				let dictData = null;
				if (this.multiSelect) {
					dictData = val.map(item => {
						return findItemFromList(this.dictDataList, item, 'id');
					}).filter(item => item != null);
				} else {
					dictData = findItemFromList(this.dictDataList, val, 'id');
				}
				this.$emit('change', tempVal, {
					dictData: dictData,
					selectRow: selectRow
				});
			},
			changeCheck(val) {
				let tempValue = this.parseValue(val);
				if (this.multiSelect && Array.isArray(tempValue) && tempValue.length > 0) {
					tempValue = tempValue.join(',') + ',';
				}
				this.$emit('input', tempValue);
			},
			loadDropdownData() {
				if (this.widget == null || !this.isDictWidget) {
					return;
				}
				this.dictDataList = [];
				let dictCall;
				if (this.form().getDictDataList) {
					if (this.form().pageCode != null) {

						let dictInfo = this.widget.props.dictInfo;
						// 报表字典
						dictCall = this.form().getDictDataList(dictInfo, this.form().getDropdownParams(this.widget));
					} else {
						let dictInfo = (this.widget.props.dictInfo || {}).dict;
						// 在线表单字典
						dictCall = this.form().getDictDataList(this, dictInfo, this.form().getDropdownParams(this.widget));
					}
					dictCall.then(res => {
						res.forEach(item => {
							item.id = item.id + '';
							if (item.parentId) item.parentId = item.parentId + '';
						});
						// 级联组件将列表转换成树
						if (this.widget.widgetType === this.SysCustomWidgetType.Cascader) {
							// res = treeDataTranslate(res, 'id', 'parentId');
						}
						if (this.widget.eventInfo && this.widget.eventInfo[this.OnlineFormEventType.DROPDOWN_CHANGE]) {
							res = this.widget.eventInfo[this.OnlineFormEventType.DROPDOWN_CHANGE](res);
						}
						this.dictDataList = res;
					}).catch(e => {});
				}
			},
			getDataSelectProps() {
				return {
					datasourceId: (this.widget.props.relativeTable || {}).datasourceId,
					relationId: (this.widget.props.relativeTable || {}).relationId,
					relativeFormId: (this.widget.props.relativeTable || {}).relativeFormId,
					variableName: (this.widget.props.relativeTable || {}).variableName,
					relationTableName: (this.widget.props.relativeTable || {}).relativeTableName,
					relationColumnName: (this.widget.props.relativeTable || {}).relativeColumn,
					displayField: (this.widget.props.relativeTable || {}).displayField
				}
			},
			reset() {
				this.loadDropdownData();
			}
		},
		computed: {
			isDictWidget() {
				return [
					this.SysCustomWidgetType.Radio,
					this.SysCustomWidgetType.CheckBox,
					this.SysCustomWidgetType.Select,
					this.SysCustomWidgetType.Cascader,
					this.SysCustomWidgetType.Tree,
					this.SysCustomWidgetType.MobileRadioFilter,
					this.SysCustomWidgetType.MobileCheckBoxFilter
				].indexOf(this.widget.widgetType) !== -1;
			},
			isLabelWidget() {
				let tempList = [
					this.SysCustomWidgetType.Label,
					this.SysCustomWidgetType.Input,
					this.SysCustomWidgetType.Switch,
					this.SysCustomWidgetType.Radio,
					this.SysCustomWidgetType.CheckBox,
					this.SysCustomWidgetType.Select,
					this.SysCustomWidgetType.Cascader,
					this.SysCustomWidgetType.Calendar,
					this.SysCustomWidgetType.Stepper,
					this.SysCustomWidgetType.Rate
				];
				return this.widget.widgetType === this.SysCustomWidgetType.Label || (tempList.indexOf(this.widget.widgetType) !== -1 && this.form().readOnly);
			},
			getColumnDataType() {
				if (this.widget == null || this.widget.column == null) return undefined;
				switch (this.widget.column.objectFieldType) {
					case 'String':
						return 'String';
					case 'Date':
						return 'Date';
					case 'Boolean':
						return 'Boolean';
					case 'Integer':
					case 'Long':
					case 'Float':
					case 'Double':
					case 'BigDecimal':
						return 'Number';
					default:
						return undefined;
				}
			},
			bindValue() {
				if (this.widget.widgetType === this.SysCustomWidgetType.Text) {
					return (this.value || this.widget.props.text || '') + '';
				}
				let bindColumnType = this.getColumnDataType;
				let tempValue = this.value;
				if (this.widget.widgetType === this.SysCustomWidgetType.Switch) {
					// 如果开关组件的字段绑定了字典，并且是只读显示，那么显示字典的值
					let dictInfo = (this.widget.column || {}).dictId;
					if ((this.form().readOnly || this.widget.props.readOnly) && dictInfo != null) {
						return tempValue;
					}
					// 根据绑定字段的类型，转换开关组件的值
					if (bindColumnType === 'Number') {
						tempValue = tempValue !== 0 && tempValue != null;
					} else if (bindColumnType === 'String') {
						tempValue = tempValue === 'true';
					} else if (bindColumnType !== 'Boolean') {
						tempValue = false;
					}
					return tempValue;
				}
				if (this.multiSelect) {
					if (Array.isArray(this.value)) return this.value;
					return (this.value || '').split(',').filter(item => item !== '');
				}
				if (this.value == null) return this.value;
				return this.isDictWidget ? (this.value + '') : this.value;
			},
			getListWidgetDataList() {
				if (this.widget.widgetType === this.SysCustomWidgetType.List) {
					if (this.widget.table && this.widget.table.relation) {
						return this.form().formData[this.widget.table.relation.variableName];
					}
				}

				return undefined;
			},
			getDisabledStatus() {
				let formAuth = this.form().formAuth ? this.form().formAuth() : null;
				if (formAuth && formAuth.mobile) {
					let formWidgetAuth = formAuth.mobile[this.widget.variableName];
					if (formWidgetAuth && formWidgetAuth.disabled) return true;
				}
				if (this.widget.eventInfo && this.widget.eventInfo[this.OnlineFormEventType.DISABLE]) {
					return this.widget.eventInfo[this.OnlineFormEventType.DISABLE]();
				} else {
					return (this.widget.props || {}).disabled;
				}
			},
			getLinkHerf() {
				let temp =
					this.widget.widgetType === this.SysCustomWidgetType.Link
						? this.widget.props.href
						: undefined;
				if (
					this.widget.eventInfo &&
					typeof this.widget.eventInfo[this.OnlineFormEventType.LINK_HERF] === 'function'
				) {
					temp = this.widget.eventInfo[this.OnlineFormEventType.LINK_HERF](this.widget.props.href);
				}
				return temp;
			},
			getWidgetProps() {
				let props = {
					...this.widget.props || {}
				};
				let tempDataList = this.widget.widgetType === this.SysCustomWidgetType.Cascader ?
					treeDataTranslate(this.dictDataList.map(item => {
						return {
							...item,
							children: undefined
						}
					}), 'id', 'parentId') : this.dictDataList;
				let widgetDisabled = this.getDisabledStatus;
				return {
					...props,
					disabled: widgetDisabled,
					clearable: true,
					filterable: true,
					readonly: this.form().readOnly || props.readonly,
					// dataList: this.dictDataList,
					dataList: tempDataList,
					label: this.widget.showName,
					widget: this.widget,
					href: this.getLinkHerf,
					props: this.widget.widgetType === this.SysCustomWidgetType.DataSelect ? {
						datasourceId: (this.widget.props.relativeTable || {}).datasourceId,
						relationId: (this.widget.props.relativeTable || {}).relationId,
						relativeFormId: (this.widget.props.relativeTable || {}).relativeFormId,
						variableName: (this.widget.props.relativeTable || {}).variableName,
						relationTableName: (this.widget.props.relativeTable || {}).relativeTableName,
						relationColumnName: (this.widget.props.relativeTable || {}).relativeColumn,
						displayField: (this.widget.props.relativeTable || {}).displayField
					} : undefined,
					rules: (this.form().rules || {})[this.widget.propString]
				};
			},
			multiSelect() {
				if (
					[
						this.SysCustomWidgetType.Select,
						this.SysCustomWidgetType.CheckBox,
						this.SysCustomWidgetType.Cascader,
						this.SysCustomWidgetType.Tree,
						this.SysCustomWidgetType.MobileRadioFilter,
						this.SysCustomWidgetType.MobileCheckBoxFilter
					].indexOf(this.widget.widgetType) === -1
				) {
					return false;
				}
				if (this.form().formType === this.SysOnlineFormType.QUERY || this.form().formType === this
					.SysOnlineFormType.ADVANCE_QUERY) {
					return this.widget.column && this.widget.column.filterType === this.SysOnlineColumnFilterType
						.MULTI_SELECT_FILTER;
				} else if (this.form().formType === this.SysOnlineFormType.REPORT) {
					return this.SysCustomWidgetType.CheckBox === this.widget.widgetType;
				} else {
					return this.widget.column && this.widget.column.fieldKind === this.SysOnlineFieldKind.MULTI_SELECT;
				}
			}
		},
		created() {
			if (this.widget) this.loadDropdownData();
			if (this.form().widgetImplList) this.form().widgetImplList[this.widget.variableName] = this;
		}
	}
</script>

<style lang="scss">
</style>